import 'aliyun-webrtc-sdk'
const AliRtcEngine = global.AliRtcEngine;

let RTC_DATA = function() {
	this.isDebug = true;
	this.aliWebrtc = null;
	this.channel_id = null;
	this.ui = null;
	this.publisherList = [];
	this.authInfo = {};
	this.userName = '';
	this.userId = '';
	this.debug = false;
	this.setChannel = (data, ui) => {
		console.log('============channel data==============', data)
		if (!this.aliWebrtc) { return }
		this.channel_id = data.channel_id;
		this.userName = data.turn.username;
		this.ui = ui;
		this.authInfo = {
			appid:data.appid,
			userid:data.userid,
			timestamp:data.timestamp,
			nonce:data.nonce,
			token:data.token,
			gslb: data.gslb,
			channel:data.channel_id
		}
		this.muteCamera(false);
		this.muteAudio(false);
		this.bindEvents();
		this.joinRoom();
	}
	this.error = (msg) => {
		alert(msg);
	}
	this.support = () => {
		this.aliWebrtc.isSupport({ isDebug: this.isDebug }).then(re => {
			console.log(re);
		}).catch(error => {
			this.error(error.message);
		})
	}
	this.bindEvents = () => {
		this.aliWebrtc.on('onJoin', (publisher) => {
			console.log("onJoin",publisher);
			if(publisher.userId){
				this.ui.updateUserList();
			}
			this.aliWebrtc.configRemoteAudio(publisher.userId, true);
			this.aliWebrtc.configRemoteCameraTrack(publisher.userId, false, true);
		});
		this.aliWebrtc.on('onPublisher', (publisher) => {
			console.log("onPublisher",publisher);
			this.userId = publisher.userId;
			let index = this.getIndexByProperty(this.publisherList, publisher.userId, 'userId');
			if (index === -1) {
				this.publisherList.push(publisher);
				this.ui.addUser(publisher.userId, publisher.displayName);
			} else {
				this.ui.updateUser(publisher.userId, publisher.displayName);
				this.updatePublisherStream(publisher, index);
			}
			this.subToggle();
		});
		this.aliWebrtc.on('onUnPublisher', (publisher) => {
			console.log("onUnPublisher",publisher);
			this.userId = '';
			this.initialization(publisher.userId);
			this.ui.removeDom(publisher.userId, publisher.displayName);
		});
		this.aliWebrtc.on('onBye', (message) => {
			if (parseInt(message.code) === 1) return this.error('被服务器踢出');
			if (parseInt(message.code) === 2) return this.error('频道关闭');
			if (parseInt(message.code) === 3) return this.error('同一个ID在其他端登录,被服务器踢出');
			this.error('onBye 未知错误');
			console.log('onBye', message);
		});
		this.aliWebrtc.on('onError', (error) => {
			console.log('onError', error)
			let msg = error && error.message ? error.message : error;
			if (msg && msg.indexOf("no session") > -1) {
				msg = "请重新登录：" + msg;
			}
			if(parseInt(error.code) === 15) {
				msg = "没有开启H5兼容";
			}
			if(error.type === "publish") {
				// 提示用户网络状态不佳
				console.log("推流断开 需要停止推流,然后重新推流");
				// 先记录当前推流状态
				var pubAudio = this.aliWebrtc.configLocalAudioPublish;
				var pubCamera = this.aliWebrtc.configLocalCameraPublish;
				var pubScreen = this.aliWebrtc.configLocalScreenPublish;
				// 设置取消推流
				this.aliWebrtc.configLocalAudioPublish = false;
				this.aliWebrtc.configLocalCameraPublish = false;
				this.aliWebrtc.configLocalScreenPublish = false;
				this.aliWebrtc.publish().then(()=>{
					console.log("推流断开取消推流成功");
					this.aliWebrtc.configLocalAudioPublish = pubAudio;
					this.aliWebrtc.configLocalCameraPublish = pubCamera;
					this.aliWebrtc.configLocalScreenPublish = pubScreen;
					this.aliWebrtc.publish().then(()=>{
						console.log("推流断开重新推流成功");
					}).catch(err => {
						console.log("推流断开重新推流失败", err);
					})
				}).catch(err => {
					console.log("推流断开取消推流失败", err);
				})
			}
			else if(error.type === "subscribe") {
				console.log("订阅断开 取消订阅该userId的所有订阅并移除所有该userId的dom");
				//先记录当前用户的订阅状态
				var subInfo = this.getSubscribeInfo(error.userId);
				//取消订阅状态
				this.initialization(error.userId);
				this.aliWebrtc.subscribe(error.userId).then(() => {
					console.log("订阅断开 取消订阅成功");
					this.aliWebrtc.configRemoteAudio(error.userId,subInfo.isSubAudio);
					this.aliWebrtc.configRemoteCameraTrack(error.userId,subInfo.isSubLarge,subInfo.isSubCamera);
					this.aliWebrtc.configRemoteScreenTrack(error.userId,subInfo.isSubScreen);
					this.aliWebrtc.subscribe(error.userId).then(() => {
						console.log("订阅断开 重新订阅成功")
						let dom = this.ui.getPatientVideo();
						this.aliWebrtc.setDisplayRemoteVideo(error.userId, dom, 1)
					}).catch(err=>{
						console.log("订阅断开 重新订阅失败", err);
						this.deletePublisher(error.userId);
						this.ui.removeDom(error.userId, error.userName);
					})
				}).catch(err => {
					console.log("订阅断开 取消订阅失败", err)
					this.deletePublisher(error.userId);
					this.ui.removeDom(error.userId, error.userName);
				});
			} else {
				this.error(msg);
			}
		});
		this.aliWebrtc.on('onLeave', (publisher) => {
			console.log('onLeave', publisher);
			this.initialization(publisher.userId);
			this.ui.updateUserList();
			this.ui.removeDom(publisher.userId, publisher.displayName);
		});
	}
	// 初始化订阅状态
	this.initialization = (userId) => {
		if (!this.aliWebrtc) return;
		this.aliWebrtc.configRemoteAudio(userId, false);
		this.aliWebrtc.configRemoteCameraTrack(userId, false, false);
		this.aliWebrtc.configRemoteScreenTrack(userId, false);
	}
	this.getIndexByProperty = (arr, val, property) => {
		let index = -1;
		arr.forEach((v, i) => {
			if (v[property] === val) {
				index = i;
			}
		});
		return index;
	}
	this.getObjByProperty = (arr, val, property) => {
		var obj = {};
		arr.forEach((v) => {
			if (v[property] === val) {
				obj = v;
			}
		});
		return obj;
	}
	this.updatePublisherStream = (publisher, index) => {
		console.log('updatePublisherStream', publisher);
		let oldStreamConfigs = JSON.parse(JSON.stringify(this.publisherList[index].streamConfigs));
		let newStreamConfigs = publisher.streamConfigs;
		const subscribeInfo = this.getSubscribeInfo(publisher.userId);
		oldStreamConfigs.forEach((v) => {
			let newStream = this.getObjByProperty(newStreamConfigs, v.label, "label");
			// 判断流状态改变了 但不确定我们是否订阅了该流
			if (v.state !== newStream.state) {
				console.log("流的状态变了" + v.label, v, v.type, ">"+ v.state + ">>" + newStream.state + ">", newStream, subscribeInfo);
				//并且要取消订阅某个流，不然就不能再次订阅了
				subscribeInfo.subscribeInfoArr.forEach(sv => {
					if (v.label === sv.label) {
						console.log("setConfigRemote取消订阅调用[api]:subscribe", publisher.userId, sv.type, sv.label);
						this.setConfigRemote(publisher.userId, sv.type, sv.label).then(() => {
							// 移除dom
							this.ui.removeDom(publisher.userId, v.label);
						}).catch(error => {
							console.error("流的状态变了重新订阅出问题", error);
						});
					}
				});
			}
		});
		this.publisherList.splice(index, 1, publisher);
	}
	this.getSubscribeInfo = (userId) => {
		const userInfo = this.aliWebrtc.getUserInfo(userId);
		let subscribeInfo = [], subscribeInfoArr = [], isSubAudio = false, isSubLarge = false,
			isSubSmall = false, isSubCamera = false, isSubScreen = false, isSubVideo = false;
		if (userInfo) {
			userInfo.streamConfigs.forEach(v => {
				if (v.subscribed) {
					subscribeInfo.push(v.label);
					subscribeInfoArr.push(v);
					v.type === "audio" ? isSubAudio = true : "";
					v.type === "video" ? isSubVideo = true : "";
					v.label === "sophon_video_camera_large" ? isSubLarge = true : "";
					v.label === "sophon_video_camera_small" ? isSubSmall = true : "";
					v.label === "sophon_video_screen_share" ? isSubScreen = true : "";
					if (isSubLarge || isSubSmall) {
						isSubCamera = true;
					}
				}
			});
		}
		return { subscribeInfo, subscribeInfoArr, isSubLarge, isSubSmall, isSubCamera, isSubAudio, isSubScreen, isSubVideo };
	}
	this.setConfigRemote = (userId, type, label) => {
		console.log('setConfigRemote');
		return new Promise((resolve) => {
			if (type === "audio") {
				this.aliWebrtc.configRemoteAudio(userId, false);
			} else {
				if (label === "sophon_video_camera_large") {
					this.aliWebrtc.configRemoteCameraTrack(userId, false, false);
					console.warn("取消相机流");
				} else if (label === "sophon_video_screen_share") {
					console.warn("取消共享流");
					this.aliWebrtc.configRemoteScreenTrack(userId, false);
				}
			}
			this.aliWebrtc.subscribe(userId).then(() => {
				resolve();
			}).catch(err => { console.error("重新订阅失败", err); alert(err.message); })
		});
	}
	this.joinRoom = () => {
		const localVideo = this.ui.getDoctorVideo();
		console.log('localVideo', localVideo);
		this.aliWebrtc.joinChannel(this.authInfo, this.userName).then(() => {
			console.log('加入房间成功');
			this.aliWebrtc.configLocalAudioPublish = true;
			this.aliWebrtc.configLocalCameraPublish = true;
			this.aliWebrtc.configLocalScreenPublish = true;
			this.aliWebrtc.publish().then(() => {
				setTimeout(() => {
					console.log("发布流成功");
				},2000);
			}, (error) => {
				console.log('推流失败', error.message);
			});
			this.aliWebrtc.startPreview(localVideo).then(() => {
				console.log('-=--------------------',  arguments)
			}).catch((error) => {
				console.log('开启预览失败', error.message);
			});
		});
	}
	this.unload = async () => {
		console.log('rtc unload', this.aliWebrtc);
		if (!this.aliWebrtc) return;
		if (!this.debug) {
			this.aliWebrtc.configLocalAudioPublish = false;
			this.aliWebrtc.configLocalCameraPublish = false;
			this.aliWebrtc.configLocalScreenPublish = false;
			await this.aliWebrtc.unPublish().then(() => {
				console.log('unPublish success');
			}, (error) => {
				console.log('unPublish error:', error.message);
			});
			this.aliWebrtc.stopPreview();
			this.aliWebrtc.dispose();
		}
	}
	this.subToggle = () => {
		if (!this.userId) return;
		let userInfo = this.aliWebrtc.getUserInfo(this.userId);
		let streamTypeList = userInfo.streamConfigs.filter(item => {
			return item.state === "active";
		});
		if (streamTypeList.length === 0) {
			return;
		}
		if (this.ui.sub()) {
			console.log('do sub');
			streamTypeList.map((item) => {
				item.userId = this.userId;
				this.receivePublishManual(item).then(re => {
					console.log("订阅成功", re);
					if (item.label === 'sophon_video_camera_large' || item.label === 'sophon_video_screen_share') {
						let dom = this.ui.getPatientVideo();
						console.log('dom:', dom, item);
						if (item.label !== 'sophon_video_screen_share') {
							this.aliWebrtc.setDisplayRemoteVideo(item.userId, dom, 1);
						} else {
							this.aliWebrtc.setDisplayRemoteVideo(item.userId, dom, 2);
						}
					}
				});
			})
		} else {
			console.log('do UnSub');
			streamTypeList.map((item) => {
				item.userId = this.userId;
				this.cancelConfigRemote(item.userId, item.label).then(re => {
					console.log('取消订阅', re);
					this.ui.removeDom(item.userId, item.userName);
				})
			});
		}
	}
	this.receivePublishManual = (v) => {
		console.log("receivePublishManual订阅", v);
		return new Promise((resolve, reject) => {
			if (v.label === "sophon_video_camera_large") {
				console.log("订阅固定视频流");
				this.aliWebrtc.configRemoteCameraTrack(v.userId, false, true);
				this.aliWebrtc.configRemoteAudio(v.userId, true);
			} else if (v.label === "sophon_video_screen_share") {
				console.log("订阅屏幕共享流");
				this.aliWebrtc.configRemoteScreenTrack(v.userId, true);
			}
			this.aliWebrtc.subscribe(v.userId).then(() => {
				resolve();
			}).catch((error) => {
				reject(error);
				this.error("[subscribe失败]" + error.message, "danger");
			});
		})
	}
	this.cancelConfigRemote = (userId, label) => {
		return new Promise((resolve) => {
			//demo中只订阅大流
			if (label === "sophon_video_camera_large") {
				this.aliWebrtc.configRemoteCameraTrack(userId, false, false);
				this.aliWebrtc.configRemoteAudio(userId,false);
			} else if (label === "sophon_video_screen_share") {
				this.aliWebrtc.configRemoteScreenTrack(userId, false);
			}
			this.aliWebrtc.subscribe(userId).then(() => {
				resolve();
			}).catch(error => console.log("取消订阅失败", error));
		})
	}
	this.deletePublisher = (userId) => {
		let index = this.getIndexByProperty(this.publisherList, userId, "userId");
		if (index !== -1) {
			this.publisherList.splice(index, 1);
			this.deletePublisher(userId);
		} else {
			console.log("未找到之前的推流数据"); //删除推流用户
		}
	}
	this.setSilent = (/*silent*/) => {
		// this.aliWebrtc.muteLocalMic(true, false);
	}
	this.muteCamera = (mute) => {
		if (!this.aliWebrtc) return;
		this.aliWebrtc.muteLocalCamera(mute);
	}
	this.muteAudio = (mute) => {
		if (!this.aliWebrtc) return;
		this.aliWebrtc.muteLocalMic(mute, false);
	}
	this.init = () => {
		// call on load
		this.aliWebrtc = new AliRtcEngine();
		this.aliWebrtc.videoProfile = { frameRate: 20, width: 480, height: 640 };
		this.support();
	}
};

export default RTC_DATA;
